#!/bin/bash

# 东宁百事通生产环境专用部署脚本
# 域名: home.dongning.fun
# 服务器: 39.96.171.44

set -e

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 配置变量
DOMAIN="home.dongning.fun"
SERVER_IP="39.96.171.44"
APP_DIR="/var/www/dongning"
LOG_DIR="/var/log/dongning"
DEPLOY_METHOD=${1:-pm2}  # docker | pm2

log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查部署环境
check_environment() {
    log_info "检查部署环境..."
    
    # 检查是否在正确的服务器上
    local current_ip=$(curl -s ifconfig.me 2>/dev/null || echo "unknown")
    if [[ "$current_ip" != "$SERVER_IP" ]]; then
        log_warning "当前IP ($current_ip) 与目标服务器IP ($SERVER_IP) 不匹配"
        read -p "是否继续部署？(y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            exit 1
        fi
    fi
    
    # 检查必要目录
    mkdir -p $APP_DIR $LOG_DIR
    
    log_success "环境检查完成"
}

# 备份当前版本
backup_current() {
    log_info "备份当前版本..."
    
    if [[ -d "$APP_DIR" ]]; then
        local backup_dir="/var/backups/dongning/$(date +%Y%m%d_%H%M%S)"
        mkdir -p "$(dirname $backup_dir)"
        cp -r "$APP_DIR" "$backup_dir"
        log_success "备份完成: $backup_dir"
    else
        log_info "首次部署，无需备份"
    fi
}

# 拉取最新代码
pull_code() {
    log_info "拉取最新代码..."
    
    if [[ -d "$APP_DIR/.git" ]]; then
        cd $APP_DIR
        git fetch origin
        git reset --hard origin/master
    else
        rm -rf $APP_DIR
        git clone https://gitee.com/wangxudongheu/dong-ning-wechat-program-server.git $APP_DIR
        cd $APP_DIR
    fi
    
    log_success "代码更新完成"
}

# 安装依赖
install_dependencies() {
    log_info "安装生产依赖..."
    
    cd $APP_DIR
    npm ci --only=production
    
    log_success "依赖安装完成"
}

# 配置环境变量
setup_environment() {
    log_info "配置生产环境变量..."
    
    cd $APP_DIR
    
    # 使用生产环境配置
    if [[ -f ".env.production" ]]; then
        cp .env.production .env
        log_success "生产环境配置已应用"
    else
        log_error "生产环境配置文件 .env.production 不存在"
        exit 1
    fi
    
    # 设置文件权限
    chmod 600 .env
    chown root:root .env
    
    log_success "环境变量配置完成"
}

# 设置文件权限
setup_permissions() {
    log_info "设置文件权限..."
    
    cd $APP_DIR
    
    # 创建必要目录
    mkdir -p File/Images/Avatar File/Images/PostImage
    
    # 设置权限
    chown -R www-data:www-data File/ || chown -R nginx:nginx File/ || true
    chmod -R 755 File/
    
    # 日志目录权限
    chown -R www-data:www-data $LOG_DIR || chown -R nginx:nginx $LOG_DIR || true
    chmod -R 755 $LOG_DIR
    
    log_success "文件权限设置完成"
}

# Docker部署
deploy_with_docker() {
    log_info "使用Docker进行生产部署..."
    
    cd $APP_DIR
    
    # 停止现有服务
    docker-compose -f docker-compose.production.yml down || true
    
    # 构建并启动服务
    docker-compose -f docker-compose.production.yml up -d --build
    
    # 等待服务启动
    log_info "等待服务启动..."
    sleep 30
    
    # 检查服务状态
    if docker-compose -f docker-compose.production.yml ps | grep -q "Up"; then
        log_success "Docker部署完成"
        docker-compose -f docker-compose.production.yml ps
    else
        log_error "Docker部署失败"
        docker-compose -f docker-compose.production.yml logs
        exit 1
    fi
}

# PM2部署
deploy_with_pm2() {
    log_info "使用PM2进行生产部署..."
    
    cd $APP_DIR
    
    # 停止现有进程
    pm2 stop dongning-backend || true
    pm2 delete dongning-backend || true
    
    # 启动应用
    pm2 start ecosystem.config.js --env production
    
    # 保存PM2配置
    pm2 save
    pm2 startup || true
    
    log_success "PM2部署完成"
    pm2 status
}

# 配置SSL证书
setup_ssl() {
    log_info "配置SSL证书..."
    
    cd $APP_DIR
    
    if [[ ! -f "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" ]]; then
        log_info "SSL证书不存在，开始获取..."
        chmod +x scripts/setup-ssl.sh
        ./scripts/setup-ssl.sh
    else
        log_info "SSL证书已存在，检查有效期..."
        if openssl x509 -checkend 2592000 -noout -in "/etc/letsencrypt/live/$DOMAIN/fullchain.pem"; then
            log_success "SSL证书有效期充足"
        else
            log_warning "SSL证书即将过期，尝试续期..."
            certbot renew --quiet --post-hook "systemctl reload nginx"
        fi
    fi
}

# 配置Nginx
setup_nginx() {
    log_info "配置Nginx..."
    
    # 如果使用PM2部署，需要配置Nginx
    if [[ "$DEPLOY_METHOD" == "pm2" ]]; then
        # 复制Nginx配置
        cp $APP_DIR/nginx/conf.d/dongning.conf /etc/nginx/sites-available/dongning
        ln -sf /etc/nginx/sites-available/dongning /etc/nginx/sites-enabled/dongning
        
        # 删除默认配置
        rm -f /etc/nginx/sites-enabled/default
        
        # 测试配置
        nginx -t
        systemctl reload nginx
        
        log_success "Nginx配置完成"
    fi
}

# 健康检查
health_check() {
    log_info "进行健康检查..."
    
    local max_attempts=20
    local attempt=1
    
    while [[ $attempt -le $max_attempts ]]; do
        if curl -f -k https://$DOMAIN/health &> /dev/null; then
            log_success "健康检查通过 - https://$DOMAIN/health"
            return 0
        elif curl -f http://localhost:3000/health &> /dev/null; then
            log_success "本地健康检查通过"
            return 0
        fi
        
        log_warning "健康检查失败，重试中... ($attempt/$max_attempts)"
        sleep 10
        ((attempt++))
    done
    
    log_error "健康检查失败"
    return 1
}

# 显示部署信息
show_deployment_info() {
    log_success "🎉 部署完成！"
    echo
    log_info "部署信息:"
    echo "  域名: https://$DOMAIN"
    echo "  服务器: $SERVER_IP"
    echo "  应用目录: $APP_DIR"
    echo "  日志目录: $LOG_DIR"
    echo "  部署方式: $DEPLOY_METHOD"
    echo
    log_info "访问地址:"
    echo "  主页: https://$DOMAIN"
    echo "  健康检查: https://$DOMAIN/health"
    echo
    log_info "管理命令:"
    if [[ "$DEPLOY_METHOD" == "docker" ]]; then
        echo "  查看状态: docker-compose -f docker-compose.production.yml ps"
        echo "  查看日志: docker-compose -f docker-compose.production.yml logs -f"
        echo "  重启服务: docker-compose -f docker-compose.production.yml restart"
    else
        echo "  查看状态: pm2 status"
        echo "  查看日志: pm2 logs dongning-backend"
        echo "  重启服务: pm2 restart dongning-backend"
    fi
}

# 主部署流程
main() {
    log_info "开始生产环境部署..."
    log_info "域名: $DOMAIN"
    log_info "部署方式: $DEPLOY_METHOD"
    
    check_environment
    backup_current
    pull_code
    install_dependencies
    setup_environment
    setup_permissions
    
    if [[ "$DEPLOY_METHOD" == "docker" ]]; then
        deploy_with_docker
    else
        deploy_with_pm2
        setup_nginx
    fi
    
    setup_ssl
    health_check
    show_deployment_info
}

# 执行主函数
main "$@"